using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Tao.OpenGl;
using Tao.FreeGlut;
using LibNDSFormats.NSBMD;

namespace MKDS_Course_Editor
{
    public partial class NSBTA_editor : Form
    {
        string file;
        string tex;
        NSBTA.NSBTA.NSBTA_File ns;
        NSBTX.nsbtx_.NSBTX_File nsbtx;
        public NSBTA_editor(string file, string tex)
        {
            this.file = file;
            this.tex = tex;
            InitializeComponent();
            simpleOpenGlControl1.InitializeContexts();
            simpleOpenGlControl1.MouseWheel += new MouseEventHandler(simpleOpenGlControl1_MouseWheel);
        }
        List<string> texNameIdex = new List<string>();
        private void NSBTA_editor_Load(object sender, EventArgs e)
        {
            ns = NSBTA.NSBTA.Read(file);
            NSBTX.nsbtx_ n = new NSBTX.nsbtx_(tex, false);
            n.ShowDialog();
            nsbtx = n.nsbtx;
            for (int i = 0; i < ns.MAT.num_objs; i++)
            {
                listBox1.Items.Add(ns.MAT.names[i]);
            }
            for (int i = 0; i < nsbtx.TexInfo.num_objs; i++)
            {
                listBox3.Items.Add(nsbtx.TexInfo.names[i]);
            }
            for (int i = 0; i < nsbtx.PalInfo.num_objs; i++)
            {
                listBox2.Items.Add(nsbtx.PalInfo.names[i]);
            }
        }
        private void simpleOpenGlControl1_Resize(object sender, EventArgs e)
        {
            simpleOpenGlControl1.Invalidate();
            RenderFunc1();
        }
        void simpleOpenGlControl1_MouseWheel(object sender, MouseEventArgs e)
        {
            dist += (float)e.Delta / 1000;
            simpleOpenGlControl1.Invalidate();
            RenderFunc1();
        }
        public bool wire = false;
        public int fix = 0;
        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            switch (keyData)
            {
                case Keys.Right:
                    ang += 1;
                    simpleOpenGlControl1.Invalidate();
                    RenderFunc1(); ;
                    return true;
                case Keys.Left:
                    ang -= 1;
                    simpleOpenGlControl1.Invalidate();
                    RenderFunc1(); ;
                    return true;
                case Keys.Up:
                    elev += 1;
                    simpleOpenGlControl1.Invalidate();
                    RenderFunc1(); ;
                    return true;
                case Keys.Down:
                    elev -= 1;
                    simpleOpenGlControl1.Invalidate();
                    RenderFunc1(); ;
                    return true;
                case Keys.Z:
                    X -= 0.1f;
                    simpleOpenGlControl1.Invalidate();
                    RenderFunc1(); ;
                    return true;
                case Keys.X:
                    X += 0.1f;
                    simpleOpenGlControl1.Invalidate();
                    RenderFunc1(); ;
                    return true;
                case Keys.A:
                    Y -= 0.1f;
                    simpleOpenGlControl1.Invalidate();
                    RenderFunc1(); ;
                    return true;
                case Keys.S:
                    Y += 0.1f;
                    simpleOpenGlControl1.Invalidate();
                    RenderFunc1(); ;
                    return true;
                case Keys.Escape:
                    X = 0.0f;
                    Y = 0.0f;
                    ang = 0.0f;
                    dist = 0.0f;
                    elev = 0.0f;
                    simpleOpenGlControl1.Invalidate();
                    RenderFunc1(); ;
                    return true;
                case Keys.T:
                    elev = 90;
                    ang = 0;
                    simpleOpenGlControl1.Invalidate();
                    RenderFunc1(); ;
                    return true;
                default:
                    return base.ProcessCmdKey(ref msg, keyData);
            }
        }

        RGBA[] image = new RGBA[0];
        public static float X = 0.0f;
        public static float Y = 0.0f;
        public static float ang = 0.0f;
        public static float dist = 0.0f;//2.5
        public static float elev = 0.0f;
        private void RenderFunc1()
        {
           /* Gl.glViewport(0, 0, this.Width, Height);
            var vp = new[] { 0f, 0f, 0f, 0f };
            Gl.glGetFloatv(Gl.GL_VIEWPORT, vp);
            float aspect = (vp[2] - vp[0]) / (vp[3] - vp[1]);
            Gl.glMatrixMode(Gl.GL_PROJECTION);
            Gl.glLoadIdentity();
            Glu.gluPerspective(90.0f, aspect, 0.02f, 32.0f);


            Gl.glEnable(Gl.GL_DEPTH_TEST);
            Gl.glEnable(Gl.GL_TEXTURE_2D);

            Gl.glEnable(Gl.GL_ALPHA_TEST);

            Gl.glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE_MINUS_SRC_ALPHA);
            Gl.glEnable(Gl.GL_BLEND);
            Gl.glAlphaFunc(Gl.GL_GREATER, 0f);
            Gl.glMatrixMode(Gl.GL_MODELVIEW);
            Gl.glLoadIdentity();
            if (true)
            {
                Gl.glBindTexture(Gl.GL_TEXTURE_2D, 0);
                Gl.glBegin(Gl.GL_LINES);
                Gl.glColor3f(1.0f, 1.0f, 1.0f);
                Gl.glVertex3f(0.0f, 0.0f, 0.0f);
                Gl.glVertex3f(1.0f, 0.0f, 0.0f);
                Gl.glVertex3f(0.0f, 0.0f, 0.0f);
                Gl.glVertex3f(0.0f, 1.0f, 0.0f);
                Gl.glVertex3f(0.0f, 0.0f, 0.0f);
                Gl.glVertex3f(0.0f, 0.0f, 1.0f);
                Gl.glEnd();
                Gl.glRasterPos3f(1.0f, 0.0f, 0.0f);

                //Glut.glutBitmapCharacter(Glut.GLUT_BITMAP_HELVETICA_18, 'X');
                Gl.glRasterPos3f(0.0f, 1.0f, 0.0f);
                // Glut.glutBitmapCharacter(Glut.GLUT_BITMAP_HELVETICA_18, 'Y');
                Gl.glRasterPos3f(0.0f, 0.0f, 1.0f);

                //Glut.glutBitmapCharacter(Glut.GLUT_BITMAP_HELVETICA_18, 'Z');
            }
            Gl.glTranslatef(X, Y, -dist);
            Gl.glRotatef(elev, 1, 0, 0);
            Gl.glRotatef(ang, 0, 1, 0);

            Gl.glClearColor(0f, 0f, 1f, 1f);
            Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);
            Gl.glDisable(Gl.GL_CULL_FACE);
            Glu.GLUquadric q = Glu.gluNewQuadric();
            Glu.gluQuadricTexture(q, Gl.GL_TRUE);

           Glu.gluSphere(q, 0.0201f, 50, 50);
            int gcd = GCD(Width, Height);

            Gl.glFrustum(-(Width / gcd), (Width / gcd), -(Height / gcd), (Height / gcd), 0, 0);  // apply the projection matrix
            try
            {

                /*var mod = _nsbmd.models[0];
                if (mod == null)
                    return;
                renderer.Model = _nsbmd.models[0];
                renderer.RenderModel(file_2);
            }
            catch (Exception ex)
            {
            }
            if (image.Length != 0)
            {
                glDrawCube(/*nsbtx.TexInfo.infoBlock.TexInfo[listBox3.SelectedIndex].width / 2, nsbtx.TexInfo.infoBlock.TexInfo[listBox3.SelectedIndex].width / 2100,100, image);
            }*/

            //I am setting a state where I am editing the projection matrix...
            Gl.glMatrixMode(Gl.GL_PROJECTION);

            //Clearing the projection matrix...
            Gl.glLoadIdentity();

            Gl.glTranslatef(0, 0, 0);
            //Creating an orthoscopic view matrix going from -1 -> 1 in each
            //dimension on the screen (x, y, z). 
            //Gl.glOrtho(-1, 1, -1, 1, -1, 1);

            //Now editing the model-view matrix.
            Gl.glMatrixMode(Gl.GL_MODELVIEW);

            //Clearing the model-view matrix.
            Gl.glLoadIdentity();

            //Disabling the depth test (z will not be used to tell what object 
            //will be shown above another, only the order in which I draw them.)
            Gl.glDisable(Gl.GL_DEPTH_TEST);

            if (image.Length != 0)
            {
                int texture_ref = 0;
                Gl.glGenTextures(1, out texture_ref);

                //Tell OpenGL we will be working with that texture number.
                Gl.glBindTexture(Gl.GL_TEXTURE_2D, texture_ref);

                //Set the parameters for the texture.
                Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_S, Gl.GL_REPEAT);
                Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_T, Gl.GL_REPEAT);
                Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);
                Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR);

                var imageBytesList = new List<byte>();
                for (int k = 0; k < image.Length; ++k)
                {
                    imageBytesList.Add(image[k].R);
                    imageBytesList.Add(image[k].G);
                    imageBytesList.Add(image[k].B);
                    imageBytesList.Add(image[k].A);
                }

                var imageBytes = imageBytesList.ToArray();

                Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_TEXTURE_ENV_MODE, Gl.GL_MODULATE);
                Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA, nsbtx.TexInfo.infoBlock.TexInfo[listBox3.SelectedIndex].width, nsbtx.TexInfo.infoBlock.TexInfo[listBox3.SelectedIndex].height, 0, Gl.GL_RGBA,
                                Gl.GL_UNSIGNED_BYTE,
                                imageBytes);


                //Enable texturing on all models for now on.
                Gl.glEnable(Gl.GL_TEXTURE_2D);
                Gl.glBindTexture(Gl.GL_TEXTURE_2D, 1);

                //Define how alpha blending will work and enable alpha blending.
                Gl.glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE_MINUS_SRC_ALPHA);
                /*Gl.glEnable(Gl.GL_BLEND);*/

                //Begin drawing quads
                Gl.glBegin(Gl.GL_QUADS);
                //Define the color (blue)
                Gl.glColor3ub(255, 255, 255);

                //Draw our four points, clockwise.
                Gl.glTexCoord2f(0, 0); Gl.glVertex3f(-0.5f, 0.5f, 0f);
                Gl.glTexCoord2f(1, 0); Gl.glVertex3f(0.5f, 0.5f, 0f);
                Gl.glTexCoord2f(1, 1); Gl.glVertex3f(0.5f, -0.5f, 0f);
                Gl.glTexCoord2f(0, 1); Gl.glVertex3f(-0.5f, -0.5f, 0f);

                Gl.glEnd();
            }
        }
        // <summary> 
        /// Greatest Common Denominator (GCD). Euclidean algorithm.  
        /// </summary> 
        /// <param name="a">Width.</param> 
        /// <param name="b">Height.</param> 
        /// <returns>GCD.</returns> 
        static int GCD(int a, int b)
        {
            return b == 0 ? a : GCD(b, a % b);
        }
        public void glDrawCube(float fPlusPosition, float fMinusPosition, RGBA[] image)// To be in OpenGL style it I gave it a gl prefix
         {
            // Gl.glTranslatef(0.0f,0.0f, 0);     // viewport = 0 0 0 and this is 6 deep
             /*if (bRotateCheck == true)
             {
                 Gl.glRotatef(fRotate, 1.0f, 1.0f, 1.0f);
             }*/
             Gl.glBindTexture(Gl.GL_TEXTURE_2D, 1);
             Gl.glBegin(Gl.GL_QUADS);// start drawin the cube
             
                     //Gl.glColor3fv(color); // Color with an array of floats
                 // Draw Top of the Cube
                 Gl.glVertex3f( fPlusPosition, fPlusPosition, fMinusPosition);                     
                Gl.glVertex3f(fMinusPosition, fPlusPosition, fPlusPosition);                 
                Gl.glVertex3f(fMinusPosition, fPlusPosition, fPlusPosition);                 
                Gl.glVertex3f( fPlusPosition, fPlusPosition, fPlusPosition);                     
                // Draw Bottom of the Cube
                 Gl.glVertex3f( fPlusPosition, fMinusPosition, fPlusPosition);                     
                Gl.glVertex3f(fMinusPosition,fMinusPosition, fPlusPosition);                     
                Gl.glVertex3f(fMinusPosition,fMinusPosition, fMinusPosition);                     
                Gl.glVertex3f( fPlusPosition,fMinusPosition, fMinusPosition);                 
                // Draw Front of the Cube
                 Gl.glVertex3f( fPlusPosition, fPlusPosition, fPlusPosition);                 
                Gl.glVertex3f(fMinusPosition, fPlusPosition, fPlusPosition);                 
                Gl.glVertex3f(fMinusPosition,fMinusPosition, fPlusPosition);                 
                Gl.glVertex3f( fPlusPosition,fMinusPosition, fPlusPosition);         
                // Draw Back of the Cube
                 Gl.glVertex3f( fPlusPosition,fMinusPosition, fMinusPosition);     
                Gl.glVertex3f(fMinusPosition,fMinusPosition, fMinusPosition);                 
                Gl.glVertex3f(fMinusPosition, fPlusPosition, fMinusPosition);                     
                Gl.glVertex3f( fPlusPosition, fPlusPosition, fMinusPosition);                     
                // Draw Left of the Cube
                 Gl.glVertex3f(fMinusPosition, fPlusPosition, fPlusPosition);                 
                Gl.glVertex3f(fMinusPosition, fPlusPosition, fMinusPosition);                     
                Gl.glVertex3f(fMinusPosition,fMinusPosition, fMinusPosition);             
                Gl.glVertex3f(fMinusPosition,fMinusPosition, fPlusPosition);             
                // Draw Right of the Cube
                 Gl.glVertex3f( fPlusPosition, fPlusPosition, fMinusPosition);             
                Gl.glVertex3f( fPlusPosition, fPlusPosition, fPlusPosition);                     
                Gl.glVertex3f( fPlusPosition,fMinusPosition, fPlusPosition);                 
                Gl.glVertex3f( fPlusPosition,fMinusPosition, fMinusPosition);     
            Gl.glEnd();// end drawing the cube   
            var imageBytesList = new List<byte>();
            for (int k = 0; k < image.Length; ++k)
            {
                imageBytesList.Add(image[k].R);
                imageBytesList.Add(image[k].G);
                imageBytesList.Add(image[k].B);
                imageBytesList.Add(image[k].A);
            }

            var imageBytes = imageBytesList.ToArray();
            
            Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_TEXTURE_ENV_MODE, Gl.GL_MODULATE);
            Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA, (int)fPlusPosition * 2, (int)fPlusPosition * 2, 0, Gl.GL_RGBA,
                            Gl.GL_UNSIGNED_BYTE,
                            imageBytes);
            Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_NEAREST);
            Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_NEAREST);
            Gl.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
           /*if (bRotateCheck == true)
             {
                 fRotate += 2.5f;
             }*/
         }
        private void MakeTexture()
        {


           // Console.WriteLine("DEBUG: making texture for model '{0}'...", mod.Name);

            //for (int i = 0; i < mod.Materials.Count; i++)
            //{
                try
                {
                    if (nsbtx.TexInfo.infoBlock.TexInfo[listBox3.SelectedIndex].format == 0) // format 0 is no texture
                        return;
                    NSBTX.nsbtx_.NSBTX_File.texInfo.Info.texInfo mat = nsbtx.TexInfo.infoBlock.TexInfo[listBox3.SelectedIndex];
                    NSBTX.nsbtx_.NSBTX_File.palInfo.Info.palInfo pal = nsbtx.PalInfo.infoBlock.PalInfo[listBox2.SelectedIndex];
                    //var mat = nsbtx.TexInfo.infoBlock.TexInfo[texNameIdex.IndexOf((string)listBox1.SelectedItems[0])];
                    //if (mat == null || mat.paldata == null)
                    //    continue;
                    int pixelnum = mat.width * mat.height;


                   image = new RGBA[pixelnum];


                    switch (mat.format)
                    {
                        // No Texture
                        case 0:
                            //puts( "ERROR: format 0" );
                            return;
                            break;
                        // A3I5 Translucent Texture (3bit Alpha, 5bit Color Index)
                        case 1:
                            for (int j = 0; j < pixelnum; j++)
                            {
                                int index = mat.Image[j] & 0x1f;
                                int alpha = (mat.Image[j] >> 5);// & 7;
                                alpha = ((alpha * 4) + (alpha / 2)) * 8;// << 3;
                                image[j] = RGBA.fromColor(pal.pal[index]);
                                image[j].A = (byte)alpha;
                            }

                            break;
                        // 4-Color Palette Texture
                        case 2:
                            for (int j = 0; j < pixelnum; j++)
                            {
                                uint index = mat.Image[j / 4];
                                index = (index >> ((j % 4) << 1)) & 3;
                                image[j] = RGBA.fromColor(pal.pal[index]);
                            }
                            break;
                        // 16-Color Palette Texture
                        case 3:
                            //if (mat.color0 != 0) mat.paldata[0] = RGBA.Transparent; // made palette entry 0 transparent
                            for (int j = 0; j < pixelnum; j++)
                            {
                                var matindex = j / 2;
                                if (mat.Image.Length < matindex)
                                    continue;
                                int index = mat.Image[matindex];
                                index = (index >> ((j % 2) << 2)) & 0x0f;
                                if (pal.pal == null)
                                    continue;
                                if (index < 0 || index >= pal.pal.Length)
                                    continue;
                                if (j < 0 || j >= pixelnum)
                                    continue;
                                image[j] = RGBA.fromColor(pal.pal[index]);
                            }
                            break;
                        // 256-Color Palette Texture
                        case 4:
                            //if (mat.color0 != 0) mat.paldata[0] = RGBA.Transparent; // made palette entry 0 transparent
                            // made palette entry 0 transparent
                            for (int j = 0; j < pixelnum; j++)
                            {
                                image[j] = RGBA.fromColor(pal.pal[mat.Image[j]]);
                            }
                            break;
                        // 4x4-Texel Compressed Texture
                        case 5:
                            convert_4x4texel_b(mat.Image, mat.width, mat.height, mat.spData, pal.pal, image);
                            break;
                        // A5I3 Translucent Texture (5bit Alpha, 3bit Color Index)
                        case 6:
                            for (int j = 0; j < pixelnum; j++)
                            {
                                int index = mat.Image[j] & 0x7;
                                int alpha = (mat.Image[j] >> 3);
                                alpha *= 8; //((alpha * 4) + (alpha / 2)) << 3;
                                image[j] = RGBA.fromColor(pal.pal[index]);
                                image[j].A = (byte)alpha;
                            }
                            break;
                        // Direct Color Texture
                        case 7:
                            for (int j = 0; j < pixelnum; j++)
                            {
                                UInt16 p = (ushort)(mat.Image[j * 2] + (mat.Image[j * 2 + 1] << 8));
                                image[j].R = (byte)(((p >> 0) & 0x1f) << 3);
                                image[j].G = (byte)(((p >> 5) & 0x1f) << 3);
                                image[j].B = (byte)(((p >> 10) & 0x1f) << 3);
                                image[j].A = (byte)(((p & 0x8000) != 0) ? 0xff : 0);
                            }
                            break;
                    }
                }
                catch { }
            //}
        }
        private bool convert_4x4texel(uint[] tex, int width, int height, UInt16[] data, Color[] pal, RGBA[] rgbaOut)
        {
            int w = width / 4;
            int h = height / 4;

            // traverse 'w x h blocks' of 4x4-texel
            for (int y = 0; y < h; y++)
                for (int x = 0; x < w; x++)
                {
                    int index = y * w + x;
                    UInt32 t = tex[index];
                    UInt16 d = data[index];
                    UInt16 addr = (ushort)(d & 0x3fff);
                    UInt16 mode = (ushort)((d >> 14) & 3);

                    // traverse every texel in the 4x4 texels
                    for (int r = 0; r < 4; r++)
                        for (int c = 0; c < 4; c++)
                        {
                            int texel = (int)((t >> ((r * 4 + c) * 2)) & 3);
                            RGBA pixel = rgbaOut[(y * 4 + r) * width + (x * 4 + c)];

                            switch (mode)
                            {
                                case 0:
                                    pixel = RGBA.fromColor(pal[(addr << 1) + texel]);
                                    if (texel == 3) pixel = RGBA.Transparent; // make it transparent, alpha = 0
                                    break;
                                case 2:
                                    pixel = RGBA.fromColor(pal[(addr << 1) + texel]);
                                    break;
                                case 1:
                                    switch (texel)
                                    {
                                        case 0:
                                        case 1:
                                            pixel = RGBA.fromColor(pal[(addr << 1) + texel]);
                                            break;
                                        case 2:
                                            pixel.R = (byte)((pal[(addr << 1)].R + pal[(addr << 1) + 1].R) / 2L);
                                            pixel.G = (byte)((pal[(addr << 1)].G + pal[(addr << 1) + 1].G) / 2L);
                                            pixel.B = (byte)((pal[(addr << 1)].B + pal[(addr << 1) + 1].B) / 2L);
                                            pixel.A = 0xff;
                                            break;
                                        case 3:
                                            pixel = RGBA.Transparent; // make it transparent, alpha = 0
                                            break;
                                    }
                                    break;
                                case 3:
                                    switch (texel)
                                    {
                                        case 0:
                                        case 1:
                                            pixel = RGBA.fromColor(pal[(addr << 1) + texel]);
                                            break;
                                        case 2:
                                            pixel.R = (byte)((pal[(addr << 1)].R * 5L + pal[(addr << 1) + 1].R * 3L) / 8);
                                            pixel.G = (byte)((pal[(addr << 1)].G * 5L + pal[(addr << 1) + 1].G * 3L) / 8);
                                            pixel.B = (byte)((pal[(addr << 1)].B * 5L + pal[(addr << 1) + 1].B * 3L) / 8);
                                            pixel.A = 0xff;
                                            break;
                                        case 3:
                                            pixel.R = (byte)((pal[(addr << 1)].R * 3L + pal[(addr << 1) + 1].R * 5L) / 8);
                                            pixel.G = (byte)((pal[(addr << 1)].G * 3L + pal[(addr << 1) + 1].G * 5L) / 8);
                                            pixel.B = (byte)((pal[(addr << 1)].B * 3L + pal[(addr << 1) + 1].B * 5L) / 8);
                                            pixel.A = 0xff;
                                            break;
                                    }
                                    break;
                            }
                            rgbaOut[(y * 4 + r) * width + (x * 4 + c)] = pixel;
                        }
                }
            return true;
        }

        /// <summary>
        /// Convert texel (wrapper for type safety issues).
        /// </summary>
        private void convert_4x4texel_b(byte[] tex, int width, int height, byte[] data, Color[] pal, RGBA[] rgbaOut)
        {
            var list1 = new List<uint>();
            for (int i = 0; i < (tex.Length + 1) / 4; ++i)
                list1.Add(LibNDSFormats.Utils.Read4BytesAsUInt32(tex, i * 4));

            var list2 = new List<UInt16>();
            for (int i = 0; i < (data.Length + 1) / 2; ++i)
                list2.Add(LibNDSFormats.Utils.Read2BytesAsUInt16(data, i * 2));
            var b = convert_4x4texel(list1.ToArray(), width, height, list2.ToArray(), pal, rgbaOut);
        }

        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (listBox1.SelectedIndex == -1)
            {
                listBox1.SelectedIndex = 0;
            }
            if (listBox2.SelectedIndex == -1)
            {
                listBox2.SelectedIndex = 0;
            }
            if (listBox3.SelectedIndex == -1)
            {
                listBox3.SelectedIndex = 0;
            }
            frameControl1.Frames.Clear();
            for (int i = 0; i < ns.MAT.infoBlock.Data[listBox1.SelectedIndex].frame[0]; i++)
            {
                frameControl1.Frames.Add(new FrameControl.AnimFrame(Properties.Resources.question_white, "Frame "+(i+1).ToString(), false, frameControl1));
            }
            frameControl1.update();
            MakeTexture();
            simpleOpenGlControl1.Invalidate();
            RenderFunc1();
        }

 
    }
}
